package com.eastfair.auth.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.auth.dao.ResourceOrganizationMapper;
import com.eastfair.auth.dto.OrganizationSaveDTO;
import com.eastfair.auth.dto.ResourceOrganizationSaveDTO;
import com.eastfair.auth.entity.ResourceOrganization;
import com.eastfair.auth.enumeration.ResourceOrganizationResourceTypeEnum;
import com.eastfair.auth.service.ResourceOrganizationService;
import com.eastfair.auth.vo.ResourceOrganizationVo;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.cache.auth.ResourceOrganizationCacheKeyBuilder;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 业务实现类
 *
 * </p>
 *
 * @author ligang
 * @date 2021-07-19
 */
@Slf4j
@Service
@Transactional
@DS("#thread.tenant")
public class ResourceOrganizationServiceImpl extends SuperCacheServiceImpl<ResourceOrganizationMapper, ResourceOrganization> implements ResourceOrganizationService {
    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(ResourceOrganization entity) {
        UpdateWrapper<ResourceOrganization> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(ResourceOrganization::getProjectId, entity.getProjectId()).eq(ResourceOrganization::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(ResourceOrganization model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(model.getProjectId()));
        return R.successDef();
    }

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new ResourceOrganizationCacheKeyBuilder();
    }


    @Override

    public R del(Long id, Long projectId) {
        ResourceOrganization resourceOrganization = new ResourceOrganization();
        resourceOrganization.setId(id);
        resourceOrganization.setIsDeleted(BusinessConstant.DELETE_YES);
        resourceOrganization.setProjectId(projectId);
        updateByIdOfShard(resourceOrganization);
        return R.successDef();
    }

    @Override
    public R delOfOrgIds(List<Long> orgIds) {
        List<ResourceOrganization> resourceOrganizationList = listOfResourceOrganization(null, orgIds, null);
        if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
            for (ResourceOrganization resourceOrganization : resourceOrganizationList) {
                resourceOrganization.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(resourceOrganization);
            }
        }
        return R.successDef();
    }


    @Override
    public R createResource(ResourceOrganizationSaveDTO resourceOrganizationSaveDTO) {
        //创建项目组织
        ResourceOrganization resourceOrganization = new ResourceOrganization();
        BeanUtils.copyProperties(resourceOrganizationSaveDTO, resourceOrganization);
        if (resourceOrganization.getResourceType() == null) {
            resourceOrganization.setResourceType(ResourceOrganizationResourceTypeEnum.OTHER);
        }
        save(resourceOrganization);
        return R.success(resourceOrganization);
    }

    @Override
    public R delResource(Long resourceId) {
        List<ResourceOrganization> resourceOrganizationList = findResource(resourceId);
        if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
            for (ResourceOrganization resourceOrganization : resourceOrganizationList) {
                resourceOrganization.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(resourceOrganization);
            }
        }
        return R.success();
    }

    @Override
    public List<ResourceOrganization> findResource(Long resourceId) {
        ResourceOrganization resourceOrganization = new ResourceOrganization();
        resourceOrganization.setResourceId(resourceId);
        List<ResourceOrganization> resourceOrganizationList = listOfResourceOrganization(resourceOrganization, null, null);
        if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
            return resourceOrganizationList;
        }
        return null;
    }

    @Override
    public R updResource(OrganizationSaveDTO organizationSaveDTO, ResourceOrganizationSaveDTO resourceOrganizationSaveDTO) {
        return null;
    }

    @Override
    public List<ResourceOrganization> queryResources(ResourceOrganization resourceOrganization, List<Long> orgIds, List<Long> ids) {
        return listOfResourceOrganization(resourceOrganization, orgIds, ids);
    }

    @Override
    public List<ResourceOrganizationVo> queryResource(List<Long> orgIds) {
        List<ResourceOrganization> resourceOrganizationList = listOfResourceOrganization(null, orgIds, null);
        if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
            return doToVos(resourceOrganizationList);
        }
        return null;
    }

    @Override
    public List<ResourceOrganization> listOfResourceOrganization(ResourceOrganization resourceOrganization, List<Long> orgIds, List<Long> ids) {
        //查询
        QueryWrapper<ResourceOrganization> queryWrapper = new QueryWrapper<>();
        if (resourceOrganization != null) {
            if (resourceOrganization.getId() != null) {
                queryWrapper.lambda().eq(ResourceOrganization::getId, resourceOrganization.getId());
            }
            if (resourceOrganization.getOrganizationId() != null) {
                queryWrapper.lambda().eq(ResourceOrganization::getOrganizationId, resourceOrganization.getOrganizationId());
            }
            if (resourceOrganization.getResourceType() != null) {
                queryWrapper.lambda().eq(ResourceOrganization::getResourceType, resourceOrganization.getResourceType());
            }

            if (resourceOrganization.getResourceId() != null) {
                queryWrapper.lambda().eq(ResourceOrganization::getResourceId, resourceOrganization.getResourceId());
            }
        }

        if (resourceOrganization != null && resourceOrganization.getProjectId() != null) {
            queryWrapper.lambda().eq(ResourceOrganization::getProjectId, resourceOrganization.getProjectId());
        } else if (ContextUtil.getProjectId() != null) {
            queryWrapper.lambda().eq(ResourceOrganization::getProjectId, ContextUtil.getProjectId());
        }

        if (orgIds != null && !orgIds.isEmpty()) {
            queryWrapper.lambda().in(ResourceOrganization::getOrganizationId, orgIds);
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(ResourceOrganization::getId, ids);
        }
        queryWrapper.lambda().eq(ResourceOrganization::getIsDeleted, BusinessConstant.DELETE_NO);
        List<ResourceOrganization> organizationList = list(queryWrapper);
        return organizationList;
    }


    public ResourceOrganizationVo doToVo(ResourceOrganization resourceOrganization) {
        ResourceOrganizationVo resourceOrganizationVo = new ResourceOrganizationVo();
        BeanUtils.copyProperties(resourceOrganization, resourceOrganizationVo);
        resourceOrganizationVo.setId(resourceOrganization.getId());
        return resourceOrganizationVo;
    }

    public List<ResourceOrganizationVo> doToVos(List<ResourceOrganization> resourceOrganizationList) {
        if (resourceOrganizationList == null || resourceOrganizationList.isEmpty()) {
            return null;
        }
        List<ResourceOrganizationVo> result = new ArrayList<>();
        for (ResourceOrganization resourceOrganization : resourceOrganizationList) {
            result.add(doToVo(resourceOrganization));
        }
        return result;
    }


}
